﻿using FySystem.Data.OrmA.Ext;
using FySystem.Data.OrmA.Formatter;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Security.Cryptography;
using System.Text;

namespace FySystem.Data.OrmA.Db
{
    class DBHelper : IDisposable
    {
        private DbConnection dbConnection;
        private DbTransaction dbTransaction;

        /// <summary>
        /// 创建连接
        /// </summary>
        internal void CreateConnection(DbConfigs dbConfig)
        {
            try
            {
                if (dbConfig == null)
                    throw new Exception("传入数据库配置为空~");

                dbConnection = dbConfig.DbProviderFactory.CreateConnection();
                dbConnection.ConnectionString = dbConfig.ConnStr;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 打开连接
        /// </summary>
        internal void Open()
        {
            try
            {
                dbConnection.Open();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 开始事务
        /// </summary>
        internal void BeginTransaction()
        {
            try
            {
                dbTransaction = dbConnection.BeginTransaction();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 回滚事务
        /// </summary>
        internal void RollbackTransaction()
        {
            try
            {
                if (dbTransaction != null)
                    dbTransaction.Rollback();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 提交事务
        /// </summary>
        internal void CommitTransaction()
        {
            try
            {
                if (dbTransaction != null)
                    dbTransaction.Commit();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取首行首列数据
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        internal object ExecuteScalar(DbProviderFactory dbProviderFactory, string sql, params DbParameter[] parameters)
        {
            object res = null;
            try
            {
                using (DbCommand command = dbProviderFactory.CreateCommand())
                {
                    command.Connection = dbConnection;
                    command.CommandText = sql;
                    if(dbTransaction != null)
                        command.Transaction = dbTransaction;
                    if (!parameters.IsNullOrEmpty())
                        command.Parameters.AddRange(parameters);

                    res = command.ExecuteScalar();
                    if (res == null)
                        return null;
                    else if (res.Equals(DBNull.Value))
                        return null;

                    res = string.IsNullOrWhiteSpace(res.ToString()) ? null : res;
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        internal int ExecuteNonQuery(DbProviderFactory dbProviderFactory,string sql,params DbParameter[] parameters)
        {
            int res = 0;
            try
            {
                using(DbCommand command = dbProviderFactory.CreateCommand())
                {
                    command.Connection = dbConnection;
                    command.CommandText = sql;
                    if (dbTransaction != null)
                        command.Transaction = dbTransaction;
                    if (!parameters.IsNullOrEmpty())
                        command.Parameters.AddRange(parameters);

                    res = command.ExecuteNonQuery();
                }
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 创建数据库Command
        /// </summary>
        /// <param name="formatResult"></param>
        /// <returns></returns>
        internal DbCommand CreateDbCommand(FormatResult formatResult, CommandType commandType)
        {
            DbCommand res = null;
            try
            {
                res = dbConnection.CreateCommand();
                res.CommandType = commandType;
                res.CommandText = formatResult.Sql;
                res.Transaction = dbTransaction;
                if (formatResult.Parameters != null)
                    res.Parameters.AddRange(formatResult.Parameters);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        public void Dispose()
        {
            try
            {
                if (dbConnection != null)
                    dbConnection.Dispose();
                if (dbTransaction != null)
                    dbTransaction.Dispose();
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
